{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "gapic-vizier-multi-objective-optimization.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AksIKBzZ-nre"
   },
   "source": [
    "# Using Vertex Vizier to Optimize Multiple Objectives\n",
    "\n",
    "## Overview\n",
    "\n",
    "In this lab, you will use [Vertex Vizier](https://cloud.google.com/vertex-ai/docs/vizier/overview) to perform multi-objective optimization. Multi-objective optimization is concerned with mathematical optimization problems involving more than one objective function to be optimized simultaneously\n",
    "\n",
    "## Objective\n",
    "\n",
    "The goal is to __`minimize`__ the objective metric:\n",
    "   ```\n",
    "   y1 = r*sin(theta)\n",
    "   ```\n",
    "\n",
    "and simultaneously __`maximize`__ the objective metric:\n",
    "   ```\n",
    "   y2 = r*cos(theta)\n",
    "   ```\n",
    "\n",
    "that you will evaluate over the parameter space:\n",
    "\n",
    "   - __`r`__ in [0,1],\n",
    "\n",
    "   - __`theta`__ in [0, pi/2]\n",
    "\n",
    "## Introduction\n",
    "\n",
    "In this notebook, you will use [Vertex Vizier](https://cloud.google.com/vertex-ai/docs/vizier/overview) multi-objective optimization. Multi-objective optimization is concerned with mathematical optimization problems involving more than one objective function to be optimized simultaneously.\n",
    "\n",
    "Each learning objective will correspond to a __#TODO__ in this student lab notebook -- try to complete this notebook first and then review the [solution notebook](../solutions/gapic-vizier-multi-objective-optimization.ipynb).  \n",
    "\n",
    "**Make sure to enable the Vertex AI API**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "iMHz63rPbq6P"
   },
   "source": [
    "#### Install Vertex AI library\n",
    "\n",
    "Download and install Vertex AI library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "b6f3dc43494b"
   },
   "outputs": [],
   "source": [
    "# Setup your dependencies\n",
    "import os\n",
    "\n",
    "# The Google Cloud Notebook product has specific requirements\n",
    "IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
    "\n",
    "# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
    "USER_FLAG = \"\"\n",
    "if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
    "    USER_FLAG = \"--user\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "g7WlujNxbq6Q"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: google-cloud-aiplatform in /opt/conda/lib/python3.7/site-packages (1.1.1)\n",
      "Collecting google-cloud-aiplatform\n",
      "  Downloading google_cloud_aiplatform-1.3.0-py2.py3-none-any.whl (1.3 MB)\n",
      "\u001b[K     |████████████████████████████████| 1.3 MB 7.6 MB/s eta 0:00:01\n",
      "\u001b[?25hRequirement already satisfied: packaging>=14.3 in /opt/conda/lib/python3.7/site-packages (from google-cloud-aiplatform) (21.0)\n",
      "Requirement already satisfied: google-cloud-bigquery<3.0.0dev,>=1.15.0 in /opt/conda/lib/python3.7/site-packages (from google-cloud-aiplatform) (2.23.2)\n",
      "Requirement already satisfied: google-cloud-storage<2.0.0dev,>=1.32.0 in /opt/conda/lib/python3.7/site-packages (from google-cloud-aiplatform) (1.41.1)\n",
      "Requirement already satisfied: google-api-core[grpc]<3.0.0dev,>=1.26.0 in /opt/conda/lib/python3.7/site-packages (from google-cloud-aiplatform) (1.31.1)\n",
      "Requirement already satisfied: proto-plus>=1.10.1 in /opt/conda/lib/python3.7/site-packages (from google-cloud-aiplatform) (1.19.0)\n",
      "Requirement already satisfied: googleapis-common-protos<2.0dev,>=1.6.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (1.53.0)\n",
      "Requirement already satisfied: requests<3.0.0dev,>=2.18.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (2.25.1)\n",
      "Requirement already satisfied: protobuf>=3.12.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (3.16.0)\n",
      "Requirement already satisfied: setuptools>=40.3.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (49.6.0.post20210108)\n",
      "Requirement already satisfied: pytz in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (2021.1)\n",
      "Requirement already satisfied: six>=1.13.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (1.16.0)\n",
      "Requirement already satisfied: google-auth<2.0dev,>=1.25.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (1.34.0)\n",
      "Requirement already satisfied: grpcio<2.0dev,>=1.29.0 in /opt/conda/lib/python3.7/site-packages (from google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (1.38.1)\n",
      "Requirement already satisfied: rsa<5,>=3.1.4 in /opt/conda/lib/python3.7/site-packages (from google-auth<2.0dev,>=1.25.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (4.7.2)\n",
      "Requirement already satisfied: pyasn1-modules>=0.2.1 in /opt/conda/lib/python3.7/site-packages (from google-auth<2.0dev,>=1.25.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (0.2.7)\n",
      "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /opt/conda/lib/python3.7/site-packages (from google-auth<2.0dev,>=1.25.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (4.2.2)\n",
      "Requirement already satisfied: google-resumable-media<3.0dev,>=0.6.0 in /opt/conda/lib/python3.7/site-packages (from google-cloud-bigquery<3.0.0dev,>=1.15.0->google-cloud-aiplatform) (1.3.2)\n",
      "Requirement already satisfied: google-cloud-core<3.0.0dev,>=1.4.1 in /opt/conda/lib/python3.7/site-packages (from google-cloud-bigquery<3.0.0dev,>=1.15.0->google-cloud-aiplatform) (1.7.2)\n",
      "Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in /opt/conda/lib/python3.7/site-packages (from google-resumable-media<3.0dev,>=0.6.0->google-cloud-bigquery<3.0.0dev,>=1.15.0->google-cloud-aiplatform) (1.1.2)\n",
      "Requirement already satisfied: cffi>=1.0.0 in /opt/conda/lib/python3.7/site-packages (from google-crc32c<2.0dev,>=1.0->google-resumable-media<3.0dev,>=0.6.0->google-cloud-bigquery<3.0.0dev,>=1.15.0->google-cloud-aiplatform) (1.14.6)\n",
      "Requirement already satisfied: pycparser in /opt/conda/lib/python3.7/site-packages (from cffi>=1.0.0->google-crc32c<2.0dev,>=1.0->google-resumable-media<3.0dev,>=0.6.0->google-cloud-bigquery<3.0.0dev,>=1.15.0->google-cloud-aiplatform) (2.20)\n",
      "Requirement already satisfied: pyparsing>=2.0.2 in /opt/conda/lib/python3.7/site-packages (from packaging>=14.3->google-cloud-aiplatform) (2.4.7)\n",
      "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /opt/conda/lib/python3.7/site-packages (from pyasn1-modules>=0.2.1->google-auth<2.0dev,>=1.25.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (0.4.8)\n",
      "Requirement already satisfied: idna<3,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests<3.0.0dev,>=2.18.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (2.10)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.7/site-packages (from requests<3.0.0dev,>=2.18.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (2021.5.30)\n",
      "Requirement already satisfied: chardet<5,>=3.0.2 in /opt/conda/lib/python3.7/site-packages (from requests<3.0.0dev,>=2.18.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (4.0.0)\n",
      "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests<3.0.0dev,>=2.18.0->google-api-core[grpc]<3.0.0dev,>=1.26.0->google-cloud-aiplatform) (1.26.6)\n",
      "Installing collected packages: google-cloud-aiplatform\n",
      "\u001b[33m  WARNING: The script tb-gcp-uploader is installed in '/home/jupyter/.local/bin' which is not on PATH.\n",
      "  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\u001b[0m\n",
      "Successfully installed google-cloud-aiplatform-1.3.0\n"
     ]
    }
   ],
   "source": [
    "# Upgrade the specified package to the newest available version\n",
    "! pip install {USER_FLAG} --upgrade google-cloud-aiplatform"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "O8AIwN0abq6U"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "if not os.getenv(\"IS_TESTING\"):\n",
    "    # Restart the kernel after pip installs\n",
    "    import IPython\n",
    "\n",
    "    app = IPython.Application.instance()\n",
    "    app.kernel.do_shutdown(True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Dax2zrpTi2Xy"
   },
   "source": [
    "### Import libraries and define constants"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "xD60d6Q0i2X0"
   },
   "outputs": [],
   "source": [
    "# Import necessary libraries\n",
    "import datetime\n",
    "import json\n",
    "\n",
    "from google.cloud import aiplatform_v1beta1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CWuu4wmki2X3"
   },
   "source": [
    "## Tutorial\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KyEjqIdnad0w"
   },
   "source": [
    "This section defines some parameters and util methods to call Vertex Vizier APIs. Please fill in the following information to get started."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "8HCgeF8had77"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ENDPOINT: us-central1-aiplatform.googleapis.com\n",
      "REGION: us-central1\n",
      "PARENT: projects/qwiklabs-gcp-00-866bdf7714fe/locations/us-central1\n",
      "Project ID: qwiklabs-gcp-00-866bdf7714fe\n",
      "Updated property [core/project].\n"
     ]
    }
   ],
   "source": [
    "# Fill in your project ID and region\n",
    "REGION = \"[region]\"  # @param {type:\"string\"}\n",
    "PROJECT_ID = \"[your-project-id]\"  # @param {type:\"string\"}\n",
    "\n",
    "# These will be automatically filled in.\n",
    "STUDY_DISPLAY_NAME = \"{}_study_{}\".format(\n",
    "    PROJECT_ID.replace(\"-\", \"\"), datetime.datetime.now().strftime(\"%Y%m%d_%H%M%S\")\n",
    ")  # @param {type: 'string'}\n",
    "ENDPOINT = REGION + \"-aiplatform.googleapis.com\"\n",
    "PARENT = \"projects/{}/locations/{}\".format(PROJECT_ID, REGION)\n",
    "\n",
    "print(\"ENDPOINT: {}\".format(ENDPOINT))\n",
    "print(\"REGION: {}\".format(REGION))\n",
    "print(\"PARENT: {}\".format(PARENT))\n",
    "\n",
    "# If you don't know your project ID, you might be able to get your project ID\n",
    "# using gcloud command by executing the second cell below.\n",
    "if PROJECT_ID == \"\" or PROJECT_ID is None or PROJECT_ID == \"[your-project-id]\":\n",
    "    # Get your GCP project id from gcloud\n",
    "    shell_output = !gcloud config list --format 'value(core.project)' 2>/dev/null\n",
    "    PROJECT_ID = shell_output[0]\n",
    "    print(\"Project ID:\", PROJECT_ID)\n",
    "! gcloud config set project $PROJECT_ID"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8NBduXsEaRKr"
   },
   "source": [
    "### Create the study configuration\n",
    "\n",
    "The following is a sample study configuration, built as a hierarchical python dictionary. It is already filled out. Run the cell to configure the study."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "s-AHfPOASXXW"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"display_name\": \"qwiklabsgcp00866bdf7714fe_study_20210827_090124\",\n",
      "  \"study_spec\": {\n",
      "    \"algorithm\": \"RANDOM_SEARCH\",\n",
      "    \"metrics\": [\n",
      "      {\n",
      "        \"goal\": \"MINIMIZE\",\n",
      "        \"metric_id\": \"y1\"\n",
      "      },\n",
      "      {\n",
      "        \"goal\": \"MAXIMIZE\",\n",
      "        \"metric_id\": \"y2\"\n",
      "      }\n",
      "    ],\n",
      "    \"parameters\": [\n",
      "      {\n",
      "        \"double_value_spec\": {\n",
      "          \"max_value\": 1,\n",
      "          \"min_value\": 0\n",
      "        },\n",
      "        \"parameter_id\": \"r\"\n",
      "      },\n",
      "      {\n",
      "        \"double_value_spec\": {\n",
      "          \"max_value\": 1.57,\n",
      "          \"min_value\": 0\n",
      "        },\n",
      "        \"parameter_id\": \"theta\"\n",
      "      }\n",
      "    ]\n",
      "  }\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "# Parameter Configuration\n",
    "\n",
    "param_r = {\"parameter_id\": \"r\", \"double_value_spec\": {\"min_value\": 0, \"max_value\": 1}}\n",
    "\n",
    "param_theta = {\n",
    "    \"parameter_id\": \"theta\",\n",
    "    \"double_value_spec\": {\"min_value\": 0, \"max_value\": 1.57},\n",
    "}\n",
    "\n",
    "# Objective Metrics\n",
    "metric_y1 = # TODO -- Your code goes here\n",
    "\n",
    "# Objective Metrics\n",
    "metric_y2 = # TODO -- Your code goes here\n",
    "\n",
    "# Put it all together in a study configuration\n",
    "study = {\n",
    "    \"display_name\": STUDY_DISPLAY_NAME,\n",
    "    \"study_spec\": {\n",
    "        \"algorithm\": \"RANDOM_SEARCH\",\n",
    "        \"parameters\": [\n",
    "            param_r,\n",
    "            param_theta,\n",
    "        ],\n",
    "        \"metrics\": [metric_y1, metric_y2],\n",
    "    },\n",
    "}\n",
    "\n",
    "print(json.dumps(study, indent=2, sort_keys=True))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "uyXG_RKha7Kb"
   },
   "source": [
    "### Create the study\n",
    "\n",
    "Next, create the study, which you will subsequently run to optimize the two objectives."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "id": "jgskzqZX0Mkt"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "STUDY_ID: projects/391139538071/locations/us-central1/studies/4148221033615\n"
     ]
    }
   ],
   "source": [
    "# Create the study using study configuration and send request through VizierServiceClient\n",
    "vizier_client = # TODO -- Your code goes here(\n",
    "    client_options=dict(api_endpoint=ENDPOINT)\n",
    ")\n",
    "study = vizier_client.create_study(parent=PARENT, study=study)\n",
    "STUDY_ID = study.name\n",
    "print(\"STUDY_ID: {}\".format(STUDY_ID))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "dKOMBKmtkcJb"
   },
   "source": [
    "### Metric evaluation functions\n",
    "\n",
    "Next, define some functions to evaluate the two objective metrics."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "Xnl1uqnyz3Qp"
   },
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "\n",
    "# r * sin(theta)\n",
    "def Metric1Evaluation(r, theta):\n",
    "    \"\"\"Evaluate the first metric on the trial.\"\"\"\n",
    "    return r * math.sin(theta)\n",
    "\n",
    "\n",
    "# r * cos(theta)\n",
    "def Metric2Evaluation(r, theta):\n",
    "    \"\"\"Evaluate the second metric on the trial.\"\"\"\n",
    "    return r * math.cos(theta)\n",
    "\n",
    "\n",
    "def CreateMetrics(trial_id, r, theta):\n",
    "    print((\"=========== Start Trial: [{}] =============\").format(trial_id))\n",
    "\n",
    "    # Evaluate both objective metrics for this trial\n",
    "    y1 = # TODO -- Your code goes here(r, theta)\n",
    "    y2 = # TODO -- Your code goes here(r, theta)\n",
    "    print(\n",
    "        \"[r = {}, theta = {}] => y1 = r*sin(theta) = {}, y2 = r*cos(theta) = {}\".format(\n",
    "            r, theta, y1, y2\n",
    "        )\n",
    "    )\n",
    "    metric1 = {\"metric_id\": \"y1\", \"value\": y1}\n",
    "    metric2 = {\"metric_id\": \"y2\", \"value\": y2}\n",
    "\n",
    "    # Return the results for this trial\n",
    "    return [metric1, metric2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Qzn5lVpRq05U"
   },
   "source": [
    "### Set configuration parameters for running trials\n",
    "\n",
    "__`client_id`__: The identifier of the client that is requesting the suggestion. If multiple SuggestTrialsRequests have the same `client_id`, the service will return the identical suggested trial if the trial is `PENDING`, and provide a new trial if the last suggested trial was completed.\n",
    "\n",
    "__`suggestion_count_per_request`__: The number of suggestions (trials) requested in a single request.\n",
    "\n",
    "__`max_trial_id_to_stop`__: The number of trials to explore before stopping. It is set to 4 to shorten the time to run the code, so don't expect convergence. For convergence, it would likely need to be about 20 (a good rule of thumb is to multiply the total dimensionality by 10).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "5usXaZA5qvUZ"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "client_id: client1\n",
      "suggestion_count_per_request: 5\n",
      "max_trial_id_to_stop: 4\n"
     ]
    }
   ],
   "source": [
    "client_id = \"client1\"  # @param {type: 'string'}\n",
    "suggestion_count_per_request = 5  # @param {type: 'integer'}\n",
    "max_trial_id_to_stop = 4  # @param {type: 'integer'}\n",
    "\n",
    "print(\"client_id: {}\".format(client_id))\n",
    "print(\"suggestion_count_per_request: {}\".format(suggestion_count_per_request))\n",
    "print(\"max_trial_id_to_stop: {}\".format(max_trial_id_to_stop))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "UnV2SJNskm7V"
   },
   "source": [
    "### Run Vertex Vizier trials\n",
    "\n",
    "Run the trials."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "id": "opmuTntW4-eS"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Trial : r is 0.03893888417627182, theta is 0.3988419180639039.\n",
      "=========== Start Trial: [projects/391139538071/locations/us-central1/studies/4148221033615/trials/1] =============\n",
      "[r = 0.03893888417627182, theta = 0.3988419180639039] => y1 = r*sin(theta) = 0.015121970858440737, y2 = r*cos(theta) = 0.03588262390419046\n",
      "Trial : r is 0.04066320382453006, theta is 0.6858991584724603.\n",
      "=========== Start Trial: [projects/391139538071/locations/us-central1/studies/4148221033615/trials/2] =============\n",
      "[r = 0.04066320382453006, theta = 0.6858991584724603] => y1 = r*sin(theta) = 0.025754816041590654, y2 = r*cos(theta) = 0.03146721461996757\n",
      "Trial : r is 0.4042052370970049, theta is 1.106379858142033.\n",
      "=========== Start Trial: [projects/391139538071/locations/us-central1/studies/4148221033615/trials/3] =============\n",
      "[r = 0.4042052370970049, theta = 1.106379858142033] => y1 = r*sin(theta) = 0.36139306421545986, y2 = r*cos(theta) = 0.18104399143193467\n",
      "Trial : r is 0.9825916425559784, theta is 1.1259051135578624.\n",
      "=========== Start Trial: [projects/391139538071/locations/us-central1/studies/4148221033615/trials/4] =============\n",
      "[r = 0.9825916425559784, theta = 1.1259051135578624] => y1 = r*sin(theta) = 0.8869437039707677, y2 = r*cos(theta) = 0.42286783042396453\n",
      "Trial : r is 0.8216538878117338, theta is 1.3492454486236054.\n",
      "=========== Start Trial: [projects/391139538071/locations/us-central1/studies/4148221033615/trials/5] =============\n",
      "[r = 0.8216538878117338, theta = 1.3492454486236054] => y1 = r*sin(theta) = 0.8015708823932446, y2 = r*cos(theta) = 0.18055257366056138\n"
     ]
    }
   ],
   "source": [
    "trial_id = 0\n",
    "while int(trial_id) < max_trial_id_to_stop:\n",
    "    suggest_response = vizier_client.suggest_trials(\n",
    "        {\n",
    "            \"parent\": STUDY_ID,\n",
    "            \"suggestion_count\": suggestion_count_per_request,\n",
    "            \"client_id\": client_id,\n",
    "        }\n",
    "    )\n",
    "\n",
    "    for suggested_trial in suggest_response.result().trials:\n",
    "        trial_id = suggested_trial.name.split(\"/\")[-1]\n",
    "        trial = vizier_client.get_trial({\"name\": suggested_trial.name})\n",
    "\n",
    "        if trial.state in [\"COMPLETED\", \"INFEASIBLE\"]:\n",
    "            continue\n",
    "\n",
    "        for param in trial.parameters:\n",
    "            if param.parameter_id == \"r\":\n",
    "                r = param.value\n",
    "            elif param.parameter_id == \"theta\":\n",
    "                theta = param.value\n",
    "        print(\"Trial : r is {}, theta is {}.\".format(r, theta))\n",
    "\n",
    "        # Store your measurement and send the request\n",
    "        # TODO -- Your code goes here(\n",
    "            {\n",
    "                \"trial_name\": suggested_trial.name,\n",
    "                \"measurement\": {\n",
    "                    \"metrics\": # TODO -- Your code goes here(suggested_trial.name, r, theta)\n",
    "                },\n",
    "            }\n",
    "        )\n",
    "\n",
    "        response = vizier_client.complete_trial(\n",
    "            {\"name\": suggested_trial.name, \"trial_infeasible\": False}\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "i5ZTqgqBiRsq"
   },
   "source": [
    "### List the optimal solutions\n",
    "\n",
    "list_optimal_trials returns the pareto-optimal Trials for multi-objective Study or the optimal Trials for single-objective Study. In the case, we define mutliple-objective in previeous steps, pareto-optimal trials will be returned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "Or2PL1YxTr33"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "optimal_trials: optimal_trials {\n",
      "  name: \"projects/391139538071/locations/us-central1/studies/4148221033615/trials/1\"\n",
      "  state: SUCCEEDED\n",
      "  parameters {\n",
      "    parameter_id: \"r\"\n",
      "    value {\n",
      "      number_value: 0.03893888417627182\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    parameter_id: \"theta\"\n",
      "    value {\n",
      "      number_value: 0.3988419180639039\n",
      "    }\n",
      "  }\n",
      "  final_measurement {\n",
      "    metrics {\n",
      "      metric_id: \"y1\"\n",
      "      value: 0.015121970858440737\n",
      "    }\n",
      "    metrics {\n",
      "      metric_id: \"y2\"\n",
      "      value: 0.03588262390419046\n",
      "    }\n",
      "  }\n",
      "  measurements {\n",
      "    metrics {\n",
      "      metric_id: \"y1\"\n",
      "      value: 0.015121970858440737\n",
      "    }\n",
      "    metrics {\n",
      "      metric_id: \"y2\"\n",
      "      value: 0.03588262390419046\n",
      "    }\n",
      "  }\n",
      "  start_time {\n",
      "    seconds: 1630054967\n",
      "  }\n",
      "  end_time {\n",
      "    seconds: 1630054968\n",
      "  }\n",
      "  client_id: \"client1\"\n",
      "}\n",
      "optimal_trials {\n",
      "  name: \"projects/391139538071/locations/us-central1/studies/4148221033615/trials/3\"\n",
      "  state: SUCCEEDED\n",
      "  parameters {\n",
      "    parameter_id: \"r\"\n",
      "    value {\n",
      "      number_value: 0.4042052370970049\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    parameter_id: \"theta\"\n",
      "    value {\n",
      "      number_value: 1.106379858142033\n",
      "    }\n",
      "  }\n",
      "  final_measurement {\n",
      "    metrics {\n",
      "      metric_id: \"y1\"\n",
      "      value: 0.36139306421545986\n",
      "    }\n",
      "    metrics {\n",
      "      metric_id: \"y2\"\n",
      "      value: 0.18104399143193467\n",
      "    }\n",
      "  }\n",
      "  measurements {\n",
      "    metrics {\n",
      "      metric_id: \"y1\"\n",
      "      value: 0.36139306421545986\n",
      "    }\n",
      "    metrics {\n",
      "      metric_id: \"y2\"\n",
      "      value: 0.18104399143193467\n",
      "    }\n",
      "  }\n",
      "  start_time {\n",
      "    seconds: 1630054967\n",
      "  }\n",
      "  end_time {\n",
      "    seconds: 1630054969\n",
      "  }\n",
      "  client_id: \"client1\"\n",
      "}\n",
      "optimal_trials {\n",
      "  name: \"projects/391139538071/locations/us-central1/studies/4148221033615/trials/4\"\n",
      "  state: SUCCEEDED\n",
      "  parameters {\n",
      "    parameter_id: \"r\"\n",
      "    value {\n",
      "      number_value: 0.9825916425559784\n",
      "    }\n",
      "  }\n",
      "  parameters {\n",
      "    parameter_id: \"theta\"\n",
      "    value {\n",
      "      number_value: 1.1259051135578624\n",
      "    }\n",
      "  }\n",
      "  final_measurement {\n",
      "    metrics {\n",
      "      metric_id: \"y1\"\n",
      "      value: 0.8869437039707677\n",
      "    }\n",
      "    metrics {\n",
      "      metric_id: \"y2\"\n",
      "      value: 0.42286783042396453\n",
      "    }\n",
      "  }\n",
      "  measurements {\n",
      "    metrics {\n",
      "      metric_id: \"y1\"\n",
      "      value: 0.8869437039707677\n",
      "    }\n",
      "    metrics {\n",
      "      metric_id: \"y2\"\n",
      "      value: 0.42286783042396453\n",
      "    }\n",
      "  }\n",
      "  start_time {\n",
      "    seconds: 1630054967\n",
      "  }\n",
      "  end_time {\n",
      "    seconds: 1630054970\n",
      "  }\n",
      "  client_id: \"client1\"\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# List all the pareto-optimal trails\n",
    "optimal_trials = # TODO -- Your code goes here({\"parent\": STUDY_ID})\n",
    "\n",
    "print(\"optimal_trials: {}\".format(optimal_trials))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KAxfq9Fri2YV"
   },
   "source": [
    "## Cleaning up\n",
    "\n",
    "To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
    "project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial. You can also manually delete resources that you created by running the following code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "zQlLDfvlzYde"
   },
   "outputs": [],
   "source": [
    "vizier_client.delete_study({\"name\": STUDY_ID})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "gapic-vizier-multi-objective-optimization.ipynb",
   "toc_visible": true
  },
  "environment": {
   "name": "tf2-gpu.2-5.m76",
   "type": "gcloud",
   "uri": "gcr.io/deeplearning-platform-release/tf2-gpu.2-5:m76"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
